package com.fingard.dsp.bank.directbank.fngrd01;

import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptMapping;
import com.fingard.dsp.bank.directbank.bankInterface.IReceipt;
import com.fingard.dsp.bank.directbank.fngrd01.fgnet.FgTcpClient;
import com.fingard.dsp.bank.directbank.fngrd01.fgnet.FgTcpReceiver;
import com.fingard.dsp.bank.helpers.HelperResp;
import com.fingard.dsp.bank.helpers.ReceiptFileSaveHelper;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.ReqQryReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceipt;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.util.ZipHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

public class FnGrd01Receipt extends FnGrd01Base implements IReceipt {

    //private String receiptSaveToMainDir = "";

    /**
     * 入口，检测必要内容
     */
    public RetAtsReceipt qryReceipt(ReqQryReceipt p_reqReceipt) throws Exception {
        RetAtsReceipt retAts = new RetAtsReceipt(p_reqReceipt.reqHeader);
        if (StringHelper.hasAnyChar(bankFront.filePort)) {
        	retAts.respCode = "";
        	if("remotehost".equals(FGBiz.dspCenter.dspSet.receiptSaveType.toLowerCase())){
        		if(StringHelper.isNullOrEmpty(FGBiz.dspCenter.dspSet.receiptMainHostServer)){
        			retAts.respCode = "-1";
                    retAts.respInfo = "DSPSystem未配置回单主DSP服务地址receiptMainHostServer";
        		}
        	}/*else{
        		receiptSaveToMainDir = FGBiz.dspCenter.dspSet.receiptMainDir;
                if (StringHelper.isNullOrEmpty(receiptSaveToMainDir)) {
                    retAts.respCode = "-1";
                    retAts.respInfo = "DSPSystem未配置回单文件下载保存主目录receiptMainDir";
                }
        	}*/
        	if(retAts.respCode.length() == 0){
        		downReceipt(p_reqReceipt);
        		retAts.respCode = "0";
                retAts.respInfo = "后台处理中";
        	}
        } else {
            retAts.respCode = "-1";
            retAts.respInfo = "融汇通BankFront未配置文件端口";
        }
        retAts.writeRetToATS();
        return retAts;
    }

    /**
     * 下载回单
     */
    public void downReceipt(ReqQryReceipt p_reqReceipt) throws Exception {
    	this.defaultTimeoutSec = 600;
        Calendar tmpCalendarFrom = Calendar.getInstance();
        tmpCalendarFrom.setTime(p_reqReceipt.getDateFrom());

        Calendar tmpCalendarTo = Calendar.getInstance();
        tmpCalendarTo.setTime(p_reqReceipt.getDateTo());

        FnGrd01Header bankHeader = new FnGrd01Header();

        bankHeader.CommandCode = "200H0";
        if(p_reqReceipt.reqHeader.bankCode.length() == 8){
        	bankHeader.CorpBankCode = p_reqReceipt.reqHeader.bankCode.substring(5);
        }else{
        	bankHeader.CorpBankCode = getBankConfig().getMapValueByKey("corBankCodeMapping", p_reqReceipt.actNum);
        }
        if (StringHelper.isNullOrEmpty(bankHeader.CorpBankCode)) {
            WriteBankLogLn("CorpBankCode为空，请配置corBankCodeMapping映射");
        }

        int tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
        int tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
        //按日循环查询
        while (tmpIntDateFrom <= tmpIntDateTo) {
            bankHeader.TransSeqID = getQryTransID();

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, bankHeader);

            xmlWriter.writeStartElement("ReceiptQueryReq");
            xmlWriter.writeElementString("CorpAct", p_reqReceipt.actNum);
            xmlWriter.writeElementString("TransDate", Format.Date10Format.format(tmpCalendarFrom.getTime()));
            xmlWriter.writeEndDocument();
            WriteBankLogLn("查询日期：" + Format.Date10Format.format(tmpCalendarFrom.getTime()));
            
            //测试用
            //saveToMainDir("D:\\getToWork\\14-filesForDevelop\\FnGrd01\\回单下载2.zip",tmpCalendarFrom.getTime(), p_reqReceipt.actNum, bankHeader.CorpBankCode);
            //测试用
            
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    int tmpIntRespCode = -1;
                    if (StringHelper.hasAnyChar(tmpRetCode)) {
                        tmpIntRespCode = Integer.parseInt(tmpRetCode);
                        if (tmpIntRespCode >= 0) {
                            String bkTransState = tmpBkReader.getSimpleTextNotNull("TransState");
                            if (bkTransState.equals("2")) {
                                String bkFileName = tmpBkReader.getSimpleTextNotNull("FileName");
                                String bkFileLength = tmpBkReader.getSimpleTextNotNull("FileLength");
                                String tmpDownZipFile = getTempFileDirectory() + File.separator + p_reqReceipt.reqHeader.transType + "_" + bankHeader.TransSeqID + ".zip";
                                WriteBankLogLn("开始下载文件" + bkFileName + ",大小" + bkFileLength + "至临时文件" + tmpDownZipFile);

                                boolean saveResult = false;
                                if (downloadFile(bankHeader.CorpBankCode, bkFileName, Long.parseLong(bkFileLength), tmpDownZipFile)) {
                                    //byte[] bytes1 = ZipUnZip4NetUtils.uncompress(FileHelper.readFileBytes(tmpDownZipFile));
                                    //File file2 = new File(tmpDownZipFile+".zip");
                                    //FileOutputStream outFileStream = new FileOutputStream(file2);
                                    //outFileStream.write(bytes1);
                                    //outFileStream.close();
                                    //saveResult = saveToMainDir(tmpDownZipFile+".zip");
                                    WriteBankLogLn("保存至回单主目录");
                                    saveResult = saveToMainDir(tmpDownZipFile,tmpCalendarFrom.getTime(), p_reqReceipt.actNum, bankHeader.CorpBankCode);
                                } else {
                                    WriteBankLogLn("执行文件下载失败");
                                }

                                if (saveResult && getBankConfig().getValueAsBool("deleteReceiptTempFile")) {
                                    if (FileHelper.deleteFileIfExists(tmpDownZipFile)) {
                                        WriteBankLogLn("已删除临时文件：" + tmpDownZipFile);
                                    } else {
                                        WriteBankLogLn("未能删除临时文件：" + tmpDownZipFile + "，可能原因：文件不存在或被占用");
                                    }
                                }
                            }
                        }
                    }
                } else {
                    WriteBankLogLn(tmpSbMsg);
                }
            } else {
                WriteBankLogLn(tmpStrRet[0] + "-" + tmpStrRet[1]);
                WriteBankLogLn("通讯失败，本次结束");
                break;
            }

            tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
            tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
        }
    }

    private boolean saveToMainDir(String p_ZipFile,Date p_date, String p_actNum, String p_bankCode) {
        boolean tmpRetValue = false;
        try {
            String tmpTempDir = p_ZipFile + ".unzip";
            WriteBankLogLn("解压至：" + tmpTempDir);
            //测试时注释掉
            ZipHelper.unZipFiles(p_ZipFile, tmpTempDir);
            //测试时注释掉
            
            //ZipHelper.decompressZip2Files(p_ZipFile, tmpTempDir);
            //ZipHelper.doDecompress(p_ZipFile, tmpTempDir);

            File tmpDir = new File(tmpTempDir);
            File[] tmpFiles = tmpDir.listFiles();
            if (tmpFiles != null && tmpFiles.length > 0) {
            	
            	ReceiptFileSaveHelper saveHelper = new ReceiptFileSaveHelper(this);
                if (!saveHelper.checkSet(this.sbLog, "")) {
                    return false;
                }
            	
                this.WriteBankLogLn("解压后共有" + tmpFiles.length + "个文件");
                int tmpCopyCount = 0;
                boolean hasDataFile = false;
                HashMap<String, String> tmpHashMapName = new HashMap<String, String>();//存已经处理的文件名
                //HashMap<String, String> tmpHashBatAsk = new HashMap<String, String>();
                for (int i = 0; i < tmpFiles.length; i++) {
                    File eachFile = tmpFiles[i];
                    if (eachFile.getName().toLowerCase().endsWith(".data")) {
                        hasDataFile = true;
                        String fileContent = FileHelper.readToString(eachFile, "utf-8");
                        XmlTextReader xmlReader = new XmlTextReader(fileContent);
                        while (xmlReader.read("/Root/ReceiptInfo/DetailRecord")) {
                        	String tmpReceiptFileName = xmlReader.readedXElement.getSingleTextNotNull("ReceiptFileName");
                        	ReceiptMapping eachRcptMp = new ReceiptMapping();
                        	eachRcptMp.reqBatchNo = xmlReader.readedXElement.getSingleTextNotNull("ReqSeqID");
                        	eachRcptMp.askNumber = xmlReader.readedXElement.getSingleTextNotNull("PostScript");
                        	//String tmpBatAndAsk = eachRcptMp.reqBatchNo + "_" + eachRcptMp.askNumber;
                        	//tmpBatAndAsk = StringHelper.trimStartAndEnd(tmpBatAndAsk, "_");
                            if (StringHelper.hasAnyChar(eachRcptMp.askNumber)) {
                                tmpHashMapName.put(tmpReceiptFileName.toLowerCase(), eachRcptMp.askNumber);//tmpBatAndAsk
                                //tmpHashBatAsk.put(tmpBatAndAsk, tmpReceiptFileName);
                            }else{
                            	WriteBankLogLn("文件"+tmpReceiptFileName+"对应的流水号为空");
                            	continue;
                            }
                            String tmpEachFilePath = tmpTempDir + File.separator + tmpReceiptFileName;
                            File eachRecFile = new File(tmpEachFilePath);
                            if (eachRecFile.exists()) {
                            	eachRcptMp.bank = p_bankCode;
                            	String eachAmt = xmlReader.readedXElement.getSingleTextNotNull("Amount");
                            	if(StringHelper.hasAnyChar(eachAmt)){
                            		eachRcptMp.amount = new BigDecimal(eachAmt);
                            	}
                            	eachRcptMp.setBusDate(p_date);
                            	eachRcptMp.busRef = eachRcptMp.askNumber;
                            	String eachMW = xmlReader.readedXElement.getSingleTextNotNull("MoneyWay");
                            	eachMW = eachMW.toUpperCase();
                            	if("S".equals(eachMW) || "2".equals(eachMW)){
                            		eachRcptMp.moneyWay = "2";
                            	}else if("F".equals(eachMW) || "1".equals(eachMW)){
                            		eachRcptMp.moneyWay = "1";
                            	}
                            	eachRcptMp.ownAct = p_actNum;
                            	eachRcptMp.receiptNo = xmlReader.readedXElement.getSingleTextNotNull("ReceiptNum");
                            	eachRcptMp.keyName = "askNumber";
                            	eachRcptMp.srcFile = tmpReceiptFileName;
                            	
                            	//String[] spRes = StringHelper.splitFileNameAndExt(tmpReceiptFileName);
                                //String tmpExt = spRes[1];
                            	
                                HelperResp saveResp = saveHelper.saveByRcptMap(this.reqHeader, eachRcptMp, tmpEachFilePath);
                            	WriteBankLogLn("文件" + tmpReceiptFileName + " --保存为--> " + eachRcptMp.receiptFile);
                            	WriteBankLogLn(saveResp.sbMsg);
                                if (saveResp.isCompleted) {
                                	tmpCopyCount++;
                                    //listToDelete.add(localReceiptPath);
                                    //FileHelper.writeFile(dataFile, "文件" + receiptRelativePath + "推送成功!", getCharset());
                                } else if (ConnState.FAIL.equals(saveResp.connState)) {
                                    WriteBankLogLn("连接服务器失败，终止本次推送");
                                    //tmpRespCode = "-1";
                                    //tmpRespInfo = "连接服务器失败，终止本次推送";
                                    //isAllRight = false;
                                    break;
                                } else if (ConnState.CLASS_NOT_FOUND.equals(saveResp.connState)) {
                                    WriteBankLogLn(ConnState.CLASS_NOT_FOUND+"初始化类异常，终止本次推送");
                                    //tmpRespCode = "-1";
                                    //tmpRespInfo = ConnState.CLASS_NOT_FOUND+"初始化类异常，终止本次推送";
                                    //isAllRight = false;
                                    break;
                                }
                            } else {
                                WriteBankLogLn("不存在文件" + tmpEachFilePath);
                            }
                        }
                    }
                }
                if (!hasDataFile) {
                    WriteBankLogLn("没有.data文件");
                }

                for (int i = 0; i < tmpFiles.length; i++) {
                    File tmpEachFile = tmpFiles[i];
                    String[] nameExt = StringHelper.splitFileNameAndExt(tmpEachFile.getName());
                    //String tmpName = nameExt[0];
                    String tmpExt = nameExt[1];
                    if (!tmpExt.toLowerCase().equals("data")) {
                        String tmpKey = StringHelper.getFileName(tmpEachFile.getName());
                        if (!tmpHashMapName.containsKey(tmpKey.toLowerCase())) {
                            WriteBankLogLn("文件" + tmpKey + "没有对应的回单数据，不处理");
                        }
                    }
                }
                
                WriteBankLogLn("总共复制了" + tmpCopyCount + "个回单文件");
                if (tmpCopyCount > 0) {
                    tmpRetValue = true;
                }
            } else {
                WriteBankLogLn("解压后文件为空");
            }

            File[] tmpTempFiles = tmpDir.listFiles();
            for (int i = 0; i < tmpTempFiles.length; i++) {
                tmpTempFiles[i].delete();
            }
            boolean delDirResult = tmpDir.delete();
            WriteBankLogLn("删除临时文件夹：" + tmpTempDir + "：" + delDirResult);

        } catch (Exception ex) {
            tmpRetValue = false;
            WriteBankLogLn(ex);
        }
        return tmpRetValue;
    }

    private boolean downloadFile(String p_corpBankCode, String p_fileName, long p_FileLength, String p_saveToFile) throws Exception {
        boolean tmpRetValue = true;
        FileOutputStream tmpFileStream = null;
        try {
            File tmpFile = new File(p_saveToFile);
            File parentDir = new File(tmpFile.getParent());
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }
            tmpFile.createNewFile();
            tmpFileStream = new FileOutputStream(tmpFile);
            FnGrd01Header bankHeader = new FnGrd01Header();
            bankHeader.CommandCode = "400H0";
            bankHeader.CorpBankCode = p_corpBankCode;

            long tmpStartPosition = 0;
            long tmpEndPosition = 0;
            long tmpStepLen = 1024 * 1024;//1M
            String tmpCharset = getCharset();
            this.WriteBankLogLn("filePort: " + bankFront.filePort);
            FgTcpClient fgClient = new FgTcpClient(bankFront.serverIP, Integer.parseInt(bankFront.filePort), tmpCharset, this.getSbLog());
            fgClient.setTimeoutMil(getReadTimeout(15));
            while (tmpEndPosition < p_FileLength - 1) {
                bankHeader.TransSeqID = getQryTransID();
                XmlTextWriter xmlWriter = new XmlTextWriter();
                writeCommonHeader(xmlWriter, bankHeader);
                xmlWriter.writeStartElement("ReceiptFileDownLoadReq");
                xmlWriter.writeElementString("FileName", p_fileName);
                tmpEndPosition = tmpStartPosition + tmpStepLen - 1;
                if (tmpEndPosition > p_FileLength - 1) {
                    tmpEndPosition = p_FileLength - 1;
                }
                xmlWriter.writeElementString("StartPosition", "" + tmpStartPosition);
                xmlWriter.writeElementString("EndPosition", "" + tmpEndPosition);

                xmlWriter.writeEndDocument();

                String tmpReqFgXml = xmlWriter.toXmlString();
                //
                byte[] tmpBytesBody = tmpReqFgXml.getBytes(tmpCharset);
                String tmpHead = "Content-Length: " + tmpBytesBody.length + "\r\n";
                byte[] tmpBytesHead = tmpHead.getBytes(tmpCharset);

                byte[] tmpBytesSend = new byte[tmpBytesHead.length + tmpBytesBody.length];
                System.arraycopy(tmpBytesHead, 0, tmpBytesSend, 0, tmpBytesHead.length);
                System.arraycopy(tmpBytesBody, 0, tmpBytesSend, tmpBytesHead.length, tmpBytesBody.length);
                //
                WriteBankLogLn("2.下载文件，发送融汇的报文：" + tmpHead + tmpReqFgXml + "\r\n");
                long tmpGetStepLen = tmpEndPosition - tmpStartPosition + 1;
                int tmpExpectLen = Integer.parseInt("" + tmpGetStepLen);
                FgTcpReceiver bkReceiver = fgClient.downloadFileBytes(tmpBytesSend, tmpExpectLen);
                if (bkReceiver.isCompleted) {
                    WriteBankLogLn("3.下载文件，请求响应成功\r\n");
                    tmpFileStream.write(bkReceiver.recBytes, 102, bkReceiver.readedLength - 102);
                    tmpRetValue = true;
                } else {
                    tmpRetValue = false;
                    WriteBankLogLn("3.下载文件，错误信息：" + bkReceiver.connState + "-" + bkReceiver.connMsg + "\r\n");
                    break;
                }
                tmpStartPosition = tmpEndPosition + 1;
            }
        } catch (Exception ex) {
            tmpRetValue = false;
            WriteBankLogLn(ex);
        } finally {
            if (tmpFileStream != null) {
                tmpFileStream.close();
            }
        }

        return tmpRetValue;
    }
}
